# 了解异常——bug
# 异常就是程序出现了bug

# 异常发捕获方法
# 程序遇到bug，有两种情况：
# 1.整个程序因为一个BUG停止运行
# 2.对BUG进行提醒，整个程序继续运行

# 捕获异常的作用在于：提前假设某处会出现异常，做好提前准备当真的出现异常的时候，可以有后续手段进行不补救
# 基本语法:
# try:
#     可能发生错误的代码
# except:
#     如果出现异常执行的代码

try:
    f = open("abc.txt","r",encoding="UTF-8")
except:
    print("出现异常了，因为文件不存在!!!")
    f = open("abc.txt","w",encoding="UTF-8")

# 捕获指定的异常
try:
    print(name)
except NameError as e:
    print("出现了变量未定义的异常!!!")

# 捕获多个异常
try:
    num = 1 / 0
    print(name)
except (NameError,ZeroDivisionError) as e:
    print("出现了变量未定义的异常或除以0的异常!!!")

# 未正确设置捕获异常类型，将无法捕获异常
# 捕获所有异常
try:
    print(m)
except Exception as e:
    print("出现了异常!!!")
else:
    print("没有出现异常!!!")

# else 异常
try:
    print("hello")
except Exception as e:
    print("出现了异常!!!")
else:
    print("没有出现异常!!!")

# 异常的finally——表示无论是否异常都要执行的代码
try:
    f = open("d.txt","r",encoding="UTF-8")
except:
    print("出现了异常!!!")
    f = open("d.txt","w",encoding="UTF-8")
else:
    print("没有出现异常!!!")
finally:
    f.close()


# 异常的传递
# 定义一个有异常的方法
def func1():
    print("func1 开始")
    num = 1 / 0
    print("func1 结束")
# 定义一个无异常的方法
def func2():
    print("func2 开始")
    func1()
    print("func2 结束")
# 定义一个方法，调用上面的方法
def main():
    try:
        func2()
    except Exception as e:
        print(f"出现异常了,异常的信息是{e}!!!")
main()


# python 模块——是一个python文件，是一个Python文件，以.py结尾
# 模块再使用前需要先导入，导入的语法如下:
# [from 模块名] import [模块 | 类 | 变量 | 函数 | *] [as 别名]
# 常用的组合形式如下:
# import 模块名
# from 模块名 import 类、变量、方法等
# from 模块名 import *
# import 模块名 as 别名
# from 模块名 import 功能名 as 别名
# 导入时间模块
import time     # 导入Python内置的time模块（time.py 这个代码文件）
print("hello")
time.sleep(5)       # 通过 . 就可以使用模块内部的全部功能
print("world")

from time import sleep  # 只导入单一功能
print("hello")
sleep(5)
print("world")

from time import *  # 导入全部功能（不用 . ）
print("hello")
sleep(5)
print("world")

from time import sleep as pause
print("hello")
pause(5)
print("world")


# 制作自定义模块
import my_module_1
my_module_1.add(1,2)

# 导入不同模块的同名文件——执行后面的文件
from my_module_1 import test_a        # 变灰表示没有被使用
from my_module_2 import test_a
test_a(1,3)

# __main__ 变量的使用——在调用模块时，不直接输出模块内的测试内容
from my_module_1 import test_a

# __all__ 变量——只作用于 *
from my_module_1 import *
test_a(4,2)
# test_b(4,2) # __all__ 列表中没有，所以无法使用
